#include <iostream>
#include <cstring>
#include <memory>
#include <functional>
// 子进程创建所需头文件
#include <sys/types.h>
#include <sys/wait.h>
#include <jsoncpp/json/json.h>
// 套接字四件套
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string>
#include <unistd.h>
#include <signal.h>

#include "Log.hpp"
#include "Calaculate.hpp"
#include "Threadpool.hpp"
using namespace zgw;
using namespace log;
using namespace std;

uint16_t gport = 8888;

#define BACKLOG 8
#define CONV(x) (struct sockaddr *)(x)

using tast_t = function<string(string &)>;

class TcpServer
{
public:
    using test_t = std::function<void(void)>;
    TcpServer(tast_t task, uint16_t port = gport) : _port(port), _isrunning(false)
    {
        _task = task;
    }
    void Init()
    {
        _sockfd = socket(AF_INET, SOCK_STREAM, 0); // 创建套接字文件
        if (_sockfd < 0)
        {
            perror("创建套接字失败:");
            exit(-1);
        }

        struct sockaddr_in Server;
        memset(&Server, 0, sizeof(Server));
        Server.sin_addr.s_addr = INADDR_ANY;
        Server.sin_family = AF_INET;
        Server.sin_port = htons(_port);
        int n = bind(_sockfd, CONV(&Server), sizeof(Server));
        if (n < 0)
        {
            perror("bind失败:");
            exit(-1);
        }
        n = listen(_sockfd, BACKLOG);
        if (n < 0)
        {
            perror("监听失败");
            exit(-1);
        }
        signal(SIGCHLD, SIG_IGN); // 忽略子进程信号
    }
    void HandlerRequest(int clfd)
    {
        if (clfd < 0)
        {
            perror("接收失败:");
            return;
        }
        string package;
        char buffer[1024];
        int size = 1023;
        while (true)
        {
            int len = read(clfd, buffer, size);
            buffer[len] = 0;
            if (len <= 0)
            {
                break;
            }
            package += buffer;
            string ret = _task(package);
            write(clfd, ret.c_str(), ret.size());
        }
    }

    void Start()
    {
        _isrunning = true;
        while (_isrunning)
        {
            struct sockaddr_in Client;
            socklen_t len = sizeof(Client);
            int clfd = accept(_sockfd, CONV(&Client), &len); // 返回的是一个文件描述符号
            uint16_t clport = ntohs(Client.sin_port);
            string clip = inet_ntoa(Client.sin_addr);
            LOG(LogLevel::INFO) << clip << "端口:" << clport << "文件描述符号:" << clfd;
            if (clfd < 0)
            {
                perror("接收失败:");
            }
            Threadpool<test_t> *pool = Threadpool<test_t>::Getptr();
            pool->Equeue([this, clfd]()
                         { HandlerRequest(clfd);
                                     close(clfd); });
        }
    }

    ~TcpServer()
    {
    }

private:
    tast_t _task;
    bool _isrunning;
    int _sockfd;
    uint16_t _port;
};


